<template>
  <div class="w-full h-full">
    <!-- <mci-dialog
      v-model="visible"
      :title="title"
      width="1000"
      top="10vh"
      :draggable="true"
      :confirm-handle="handleConfirm"
      @close="handleClosed"
    > -->
    <div class="flex justify-center">
      <div class="w-1/2">
        <mci-steps :active="activeStep" finish-status="success">
          <mci-step title="连接API" />
          <mci-step title="提取数据" />
        </mci-steps>
      </div>
    </div>
    <div style="height: 50vh; overflow-y: auto">
      <div v-show="activeStep === 0" style="width: calc(100% - 16px)">
        <mci-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto" label-position="top">
          <!-- 接口名称 -->
          <mci-row>
            <mci-col :span="24">
              <mci-form-item label="模型名称" prop="modelName">
                <mci-input v-model="ruleForm.modelName" type="text" :maxlength="INPUT_MAX_DATA_MODEL_NAME" />
              </mci-form-item>
            </mci-col>
          </mci-row>

          <!-- API说明 -->
          <mci-row>
            <mci-col :span="24">
              <mci-form-item label="模型描述" prop="modelDesc">
                <mci-textarea v-model="ruleForm.modelDesc" :rows="4" :maxlength="INPUT_MAX_DESC" />
              </mci-form-item>
            </mci-col>
          </mci-row>

          <!-- URL -->
          <mci-row>
            <mci-col :span="24">
              <mci-form-item label="模型调用地址" prop="httpUrl">
                <!-- <mci-input
                v-model="ruleForm.httpUrl"
                class="input-with-select"
              >
                <template #prepend>
                  <mci-select
                    v-model="ruleForm.httpMethod"
                    :list="httpMethodOptions"
                    placeholder="Select"
                  >
                  </mci-select>
                </template>
              </mci-input> -->
                <el-input
                  v-model="ruleForm.httpUrl"
                  placeholder="请输入"
                  class="input-with-select"
                  :maxlength="INPUT_MAX_HTTPURL"
                >
                  <template #prepend>
                    <el-select v-model="ruleForm.httpMethod" style="width: 96px">
                      <el-option label="POST" value="POST" />
                      <el-option label="GET" value="GET" />
                    </el-select>
                  </template>
                </el-input>
              </mci-form-item>
            </mci-col>
          </mci-row>

          <mci-form-item label="选择解析工具" prop="modelTemplate">
            <div class="flex justify-end w-full">
              <div class="grow pr-8">
                <mci-select v-model="ruleForm.modelTemplate" :disabled="apiModelID" :list="templateOptions" class="w-full" @change="modelTemplateChange">
                  <mci-option
                    v-for="item in templateOptions"
                    :key="item.dictCode"
                    :label="item.dictName"
                    :value="item.dictCode"
                  />
                </mci-select>
              </div>
              <mci-button type="primary" plain :disabled="!ruleForm.modelTemplate" @click="editScript"> 编辑脚本 </mci-button>
            </div>
          </mci-form-item>

          <mci-form-item label="变量类型" prop="varMode">
            <div class="w-full">
              <div>
                <MciRadioGroup v-model="ruleForm.varMode" :direction="'row'">
                  <MciRadio :label="0" text="自定义入参" />
                  <MciRadio :label="1" text="依赖前置节点" />
                </MciRadioGroup>
              </div>
              <div v-show="ruleForm.varMode === 0" class="w-full">
                <!-- <AddBtn btn-text="新增参数" @add="addParam" /> -->
                <VariablesAdd ref="parametersAddRef" />
              </div>
            </div>
          </mci-form-item>
        </mci-form>
        <ApiModelScript ref="codeRef" @value="handleTemplateValue" />
      </div>
      <div v-show="activeStep === 1" style="width: calc(100% - 16px)">
        <!-- <JsonEditor ref="jsonEditorRef" /> -->
        <mci-label class="py-8"> 请求参数 </mci-label>
        <CodeMirrorJSON ref="jsonEditorRef" :code="jsonCode" />
        <div class="py-16 flex justify-end">
          <mci-button plain type="primary" :loading="executeLoading" @click="execute">执行</mci-button>
        </div>
        <div v-show="executeDone">
          <ApiModelDataStructure ref="apiModelDataStructureRef" :data="dataStructure.data" @change="dataStructureChange" />
          <div v-show="executeDone" class="py-16">
            <DataPreview :table-data="tesResTableData" :table-column="tesResTableColumn" />
          </div>
        </div>
      </div>
    </div>
    <!-- <template #footer>
        <span class="dialog-footer">
          <mci-button @click="visible = false">取消</mci-button>
          <mci-button v-show="activeStep" @click="last"> 上一步 </mci-button>
          <mci-button v-show="activeStep === 0" type="primary" @click="save"> 下一步 </mci-button>
          <mci-button v-show="activeStep" type="primary" :disabled="!executeDone" @click="handleConfirm"> 确定 </mci-button>
        </span>
      </template>
    </mci-dialog> -->
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue';
import { ElInput, ElSelect, ElOption } from 'element-plus';
import {
  MciButton,
  MciInput,
  MciForm,
  MciFormItem,
  MciTextarea,
  MciCol,
  MciRow,
  MciMessage,
  MciStep,
  MciSteps,
  MciSelect,
  MciOption,
  MciRadioGroup,
  MciRadio,
  MciLabel
} from '@/components/base';
import type { RuleForm } from './data';
import { INPUT_MAX_DATA_MODEL_NAME, INPUT_MAX_DESC, INPUT_MAX_HTTPURL, SerializeType } from './data';
import ApiModelScript from '../ApiModelScript/index.vue';
import ApiModelDataStructure from '../DataStructure/index.vue';
// import JsonEditor from '../JsonEditor/index.vue';
import CodeMirrorJSON from '@/components/business/CodeMirrorJSON/index.vue';
// import AddBtn from '@/views/data-source/components/DataModel/components/AddBtn/index.vue';
// import VariablesAdd from '../ApiModelVariables/index.vue';
import VariablesAdd from '@/views/data-source/components/DataModel/components/ParametersAdd/index.vue';
import DataPreview from '../DataPreview/index.vue';

import {
  postModelAdd,
  postModelExecute,
  postModelUpdate,
  postModelVariableAdd,
  getModelGet,
  getModelTemplate
} from '@/api/decision-engine';
import type {
  IPostModelAddReq,
  IPostModelAddRes,
  IPostModelExecuteReq,
  IPostModelExecuteRes,
  IPostModelUpdateReq,
  // IPostModelUpdateRes,
  IPostModelVariableAddReq,
  IGetModelGetReq,
  IGetModelGetRes,
  IGetModelTemplateReq,
  IGetModelTemplateRes
} from '@/api/decision-engine';

import { useDictStore } from '@/store/dict';
import { VarType } from '@/components/business/Nodes/DataLoad/components/DataSet/type';
import { dataModelKey } from '../../../DataModel/components/DataModelAdd/data';

const dictStore = useDictStore();
const activeStep = ref(0);
const dataStructure = reactive<any>({});

const templateOptions = ref<any[]>([]);

// const props = defineProps({
//   showAdd: Boolean
// });
const emit = defineEmits(['init', 'activeStep', 'execute', 'closed']);

onMounted(() => {
  emit('init');
});

const visible = ref(false);
const title = ref('新增模型API');
const apiModelID = ref();
// const handleClosed = () => {
//   emit('closed');
// };
// 预览数据
const tesResTableData = ref<any>([]);
const tesResTableColumn = ref<any>([]);
// 执行
const executeDone = ref(false);
const executeLoading = ref(false);

// 表单
const ruleFormRef = ref<any>();
const jsonEditorRef = ref<any>();
const jsonCode = ref('');
const apiModelDataStructureRef = ref<any>();
const ruleForm = reactive<RuleForm>({
  httpMethod: 'POST',
  modelName: '',
  modelDesc: '',
  httpUrl: '',
  serializeScript: undefined,
  serializeType: SerializeType.JSON,
  modelTemplate: '',
  varMode: 0,
  variables: [],
  paramsJson: ''
});
const rules = reactive<any>({
  modelName: [
    { required: true, message: '请填写模型名称', trigger: 'blur' }
    // { required: true, validator: validateTarget, trigger: 'blur' }
  ],
  modelDesc: [
    { required: true, message: '请填写模型描述', trigger: 'blur' }
    // { required: true, validator: validateTarget, trigger: 'blur' }
  ],
  httpUrl: [
    { required: true, message: '请填写模型调用地址', trigger: 'blur' }
    // { required: true, validator: validateTarget, trigger: 'blur' }
  ],
  modelTemplate: [
    { required: true, message: '请选择解析工具', trigger: 'blur' }
    // { required: true, validator: validateTarget, trigger: 'blur' }
  ],
  varMode: [
    { required: true, message: '请选择变量类型', trigger: 'blur' }
    // { required: true, validator: validateTarget, trigger: 'blur' }
  ]
});

//  update参数
const updateParameters = (newVal: any) => {
  ruleForm.variables = newVal;
};
provide(dataModelKey, { ruleForm, updateParameters });

const codeRef = ref<any>(null);

const formValidate = async () => {
  if (!ruleFormRef.value) return;
  await ruleFormRef.value.validate((valid: any, fields: any) => {
    if (valid) {
      if (apiModelID.value) {
        modifyRequest();
      } else {
        addRequest();
      }
    } else {
      if (fields) {
        const keys = Object.keys(fields) || [];
        for (const key of keys) {
          if (key && fields[key]) {
            for (const item of fields[key]) {
              if (item && item.message) {
                MciMessage({
                  message: item.message,
                  type: 'warning'
                });
                return;
              }
            }
          }
        }
      }
    }
  });
};

// 新增请求
const addRequest = async () => {
  const { modelName, modelDesc, httpUrl, httpMethod, serializeType, serializeScript, varMode, modelTemplate } = ruleForm;
  let variableDada = [];
  if (varMode === 0) {
    variableDada = parametersAddRef.value?.getData()?.parameters;
  }
  const params: IPostModelAddReq = {
    modelName,
    modelDesc,
    httpUrl,
    httpMethod,
    serializeType,
    serializeScript,
    modelTemplate,
    varMode,
    variables: variableDada
  };
  const data: IPostModelAddRes = await postModelAdd(params);
  if (data) {
    // 新增成功
    apiModelID.value = data;
    initNext();
  }
};

// 执行
const exeRequest = async () => {
  let json = jsonEditorRef.value.getData();

  json && json.trim();
  if (json && typeof json === 'string') {
    json = json.trim();
    try {
      if (json) json = JSON.parse(json);
    } catch (error) {
      console.error(error);
      MciMessage({
        message: 'JSON数据格式不正确，请修改后重试',
        type: 'warning'
      });
      return;
    }
  }

  executeLoading.value = true;
  const params: IPostModelExecuteReq = {
    modelId: apiModelID.value,
    param: json || {}
  };
  // const data: IPostModelExecuteRes = await postModelExecute(params);
  try {
    const data: IPostModelExecuteRes = await postModelExecute(params);

    executeDone.value = true;
    emit('execute', true);
    executeLoading.value = false;
    // 数据结构
    if (data && Array.isArray(data) && data.length) {
      dataStructure.data = data[0];
    } else {
      dataStructure.data = {};
    }
    // 数据预览
    buildDataPreview(data);
  } catch (e) {
    executeLoading.value = false;
  }
};

// 构建预览数据
const buildDataPreview = (data: any) => {
  tesResTableData.value = data || [];
  tesResTableColumn.value = [];
  if (data && data.length) {
    const keys = Object.keys(data[0]);
    tesResTableColumn.value = keys.map((item: string) => {
      return {
        label: item,
        prop: item
      };
    });
  }
};

// 数据结构变化回调

const dataStructureChange = () => {
  const newData = apiModelDataStructureRef.value?.getData();
  const columns: any = [];
  if (newData) {
    for (const iterator of newData) {
      if (iterator && iterator.checked) {
        const column = {
          label: iterator.varLabel,
          prop: iterator.varName
        };
        columns.push(column);
      }
    }
  }
  tesResTableColumn.value = columns;
};

// 修改请求
const modifyRequest = async () => {
  const { modelName, modelDesc, httpUrl, httpMethod, serializeType, serializeScript, modelTemplate, varMode } = ruleForm;
  let variableDada = [];
  if (varMode === 0) {
    variableDada = parametersAddRef.value?.getData()?.parameters;
  }
  const params: IPostModelUpdateReq = {
    id: apiModelID.value,
    modelName,
    modelDesc,
    httpUrl,
    httpMethod,
    serializeType,
    serializeScript,
    modelTemplate,
    varMode,
    variables: variableDada
  };
  await postModelUpdate(params).then(() => {
    initNext();
  });
};

const handleConfirm = () => {
  // formValidate();
  const params: IPostModelVariableAddReq = {
    modelId: apiModelID.value,
    variables: apiModelDataStructureRef.value?.getData()
  };
  postModelVariableAdd(params).then(() => {
    visible.value = false;
    emit('closed', false);
  });
};

// 执行
const execute = () => {
  exeRequest();
};

// 使用的解析模板变化回调
const modelTemplateChange = () => {
  serializeScriptRequest();
};
// 模板
const serializeScriptRequest = async () => {
  if (!ruleForm.modelTemplate) {
    return;
  }
  const params: IGetModelTemplateReq = {
    templateName: ruleForm.modelTemplate
  };
  const data: IGetModelTemplateRes = await getModelTemplate(params);
  if (data) {
    ruleForm.serializeScript = data;
  }
};
// 打开编辑脚本窗口
const editScript = () => {
  // codeRef.value && codeRef.value.initData(ruleForm.modelTemplate);
  codeRef.value && codeRef.value.initData(ruleForm.serializeScript);
};

// 获取编辑确认的脚本内容
const handleTemplateValue = (val: any) => {
  ruleForm.serializeScript = val;
};

// 保存
const save = () => {
  if (activeStep.value === 0) {
    formValidate();
  }
};

// 下一步
// const next = () => {
//   if (activeStep.value === 0 && apiModelID.value) {
//     initNext();
//   }
// };

// 初始化下一步数据
const initNext = () => {
  activeStep.value < 1 && activeStep.value++;
  emit('activeStep', activeStep.value);
  executeDone.value = false;
  emit('execute', false);
  // 清空请求数据
  // jsonEditorRef.value?.clearData();
  // 回显数据
  const jsonObj = toRaw(ruleForm).paramsJson;
  jsonCode.value = jsonObj;
  // 清空返回数据
  dataStructure.data = {};
  // try {
  //   if (jsonObj) {
  //     const jsonStr = JSON.stringify(jsonObj);
  //     jsonEditorRef.value?.setData(jsonStr);
  //   }
  //   // 清空返回数据
  //   dataStructure.data = {};
  // } catch (error) {
  //   console.log(error);
  // }
};

// 上一步
const last = () => {
  activeStep.value > 0 && activeStep.value--;
  emit('activeStep', activeStep.value);
};

const parametersAddRef = ref<any>(null);
// const addParam = () => {
//   parametersAddRef.value?.addRow();
// };

// 初始化
const initData = async (dataModel?: any) => {
  visible.value = true;
  apiModelID.value = dataModel?.id;
  title.value = '新增模型API';
  templateOptions.value = dictStore.dictApiTemplate || [];
  activeStep.value = 0;
  emit('activeStep', activeStep.value);
  executeLoading.value = false;
  jsonCode.value = '';

  // 回显
  if (apiModelID.value) {
    title.value = '修改模型API';
    const params: IGetModelGetReq = {
      id: apiModelID.value
    };
    const data: IGetModelGetRes = await getModelGet(params);
    ruleForm.modelName = data.modelName;
    ruleForm.modelDesc = data.modelDesc;
    ruleForm.httpUrl = data.httpUrl;
    ruleForm.httpMethod = data.httpMethod;
    ruleForm.serializeScript = data.serializeScript;
    ruleForm.serializeType = data.serializeType;
    ruleForm.varMode = data.varMode;
    ruleForm.modelTemplate = data.modelTemplate;
    if (data.variables) {
      ruleForm.variables = data.variables.filter((item) => item.scope === 'REQUEST')
          ?.map((item) => {
            if (
              item &&
              item.initValue &&
              typeof item.initValue === 'string' &&
              (item.varType === VarType.Date || item.varType === VarType.DateTime)
            ) {
              item.initValue = parseInt(item.initValue);
            }
            return item;
            });
    } else {
      ruleForm.variables = [];
    }
    parametersAddRef.value?.initData(ruleForm.variables);
    ruleForm.paramsJson = data.paramsJson;
    if (!ruleForm.serializeScript) {
      serializeScriptRequest();
    }
  } else {
    title.value = '新增模型API';
    ruleForm.modelName = '';
    ruleForm.modelDesc = '';
    ruleForm.httpUrl = '';
    ruleForm.httpMethod = '';
    ruleForm.serializeScript = '';
    ruleForm.serializeType = SerializeType.JSON;
    ruleForm.varMode = undefined;
    ruleForm.modelTemplate = undefined;
    ruleForm.variables = [];
  }
};

defineExpose({
  initData,
  save,
  last,
  handleConfirm
});
</script>
